/* enum */
import { FieldTypeMappingEnum } from '@model/enum/FieldMappingEnum'
/* model */
import { ConnectorField, ConnectorFieldNameEnum, ConnectorFieldTypeEnum, ConnectorOptionsAction, ConnectorToField } from '@src/modules/connector/model'
/* types */
import { ConnectorFormValueType, ConnectorServerValueType } from '@src/modules/connector/types'
/* util */
import Log from '@src/util/log'
/* model form */
import { 
  ConnectorFormValue, 
  ConnectorFormValueAddress, 
  ConnectorFormValueAttachment, 
  ConnectorFormValueCustomer, 
  ConnectorFormValueUser, 
  ConnectorFormValueCustomerAddress, 
  ConnectorFormValueLinkman, 
  ConnectorFormValueLocation, 
  ConnectorFormValueProduct, 
  ConnectorFormValueRelationTask, 
  ConnectorFormValueRelatedCustomers,
  ConnectorFormValueDate,
  ConnectorFormValueTags,
  ConnectorFormValueText,
} from '@src/modules/connector/model/form'
import { isArray } from 'lodash'

// 需要转换的字段类型
const ConnectorConvertFieldTypeMap: Record<string, ConnectorFormValue> = {
  [ConnectorFieldTypeEnum.Address]: new ConnectorFormValueAddress(),
  [ConnectorFieldTypeEnum.Attachment]: new ConnectorFormValueAttachment(),
  [ConnectorFieldTypeEnum.Customer]: new ConnectorFormValueCustomer(),
  [ConnectorFieldTypeEnum.User]: new ConnectorFormValueUser(),
  [ConnectorFieldTypeEnum.CustomerAddress]: new ConnectorFormValueCustomerAddress(),
  [ConnectorFieldTypeEnum.Linkman]: new ConnectorFormValueLinkman(),
  [ConnectorFieldTypeEnum.Location]: new ConnectorFormValueLocation(),
  [ConnectorFieldTypeEnum.Product]: new ConnectorFormValueProduct(),
  [ConnectorFieldTypeEnum.RelationTask]: new ConnectorFormValueRelationTask(),
  [ConnectorFieldTypeEnum.RelatedCustomers]: new ConnectorFormValueRelatedCustomers(),
  [ConnectorFieldTypeEnum.Text]: new ConnectorFormValueText(),
}

// 需要转换的字段名称
const ConnectorConvertFieldNameMap: Record<string, ConnectorFormValue> = {
  [ConnectorFieldNameEnum.Tags]: new ConnectorFormValueTags(),
}

/** 
 * @description 将表单值转换为服务器值
*/
function convertFormValueToServerValue(value: ConnectorFormValueType, field: ConnectorField): ConnectorServerValueType | ConnectorFormValueType {
  
  try {
    
    // @ts-ignore
    const formType = field?.formType || field?.fieldType || ''
    // @ts-ignore
    const fieldName = field?.fieldName || field?.enName || ''
    
    try {
      
      if (!field?.formType) {
        field.formType = formType
      }
      
      if (!field?.fieldName) {
        field.fieldName = fieldName
      }
      
    } catch (error) {
      
      Log.error(error, convertFormValueToServerValue.name)
      
    }
    
    // 优先匹配 fieldName
    const fieldNameFormValue = ConnectorConvertFieldNameMap[fieldName]
    if (fieldNameFormValue) {
      return fieldNameFormValue.formValueToServerValue(value, field) as ConnectorServerValueType
    }
    
    // 再匹配 formType
    const fieldTypeFormValue = ConnectorConvertFieldTypeMap[formType]
    if (fieldTypeFormValue) {
      return fieldTypeFormValue.formValueToServerValue(value, field) as ConnectorServerValueType
    }
    
    return value
    
  } catch (error) {
    
    Log.error(error, convertFormValueToServerValue.name)
    
    return value
    
  }
  
}

/** 
 * @description 将服务器值转换为表单值
*/
function convertServerValueToFormValue(value: ConnectorServerValueType, formType: FieldTypeMappingEnum | string, field: ConnectorField): ConnectorServerValueType | ConnectorFormValueType {
  
  try {
    
    const serverValue = ConnectorConvertFieldTypeMap[formType]
    
    if (serverValue) {
      return serverValue.serverValueToFormValue(value, field) as ConnectorFormValueType
    }
    
    return value
    
  } catch (error) {
    
    Log.error(error, convertServerValueToFormValue.name)
    
    return value
    
  }
  
}

type SetConnectorToFieldKey = keyof Pick<ConnectorToField, 'supportDelete' | 'supportSelect'| 'supportUpdate'| 'supportDelete' | 'supportInsert'>
type ConnectorOptionsActionKey = keyof Pick<ConnectorOptionsAction, 'toRequestFieldList' | 'toResponseFieldList'> 

const covertSetForDataKey = (dataObj: ConnectorOptionsAction, keys: ConnectorOptionsActionKey[] = [], setKeys: SetConnectorToFieldKey [])=> {

  const convertToFieldsSupportKeys = (toFields: ConnectorToField [] = [], keys: ConnectorOptionsActionKey[], setKeys: SetConnectorToFieldKey[])=> {
    toFields.forEach((field: ConnectorToField)=> {
      if(isArray(field.children)) field.children = convertToFieldsSupportKeys(field.children, keys, setKeys)
      setKeys.forEach(setKey=> {
        field[setKey] = field[setKey] ? field[setKey] || true : true
      })
    })
    return toFields
  }

  keys.forEach((key: ConnectorOptionsActionKey) => {
    if(Reflect.has(dataObj, key) && dataObj[key]) {
      dataObj[key] = convertToFieldsSupportKeys(dataObj[key], keys, setKeys)
    }
  })
  return dataObj
}


export {
  covertSetForDataKey,
  convertFormValueToServerValue,
  convertServerValueToFormValue
}